package com.fxkj.cloud.drms.domain.ts.service;

import com.fxkj.cloud.dbs.common.model.kv.TsKvEntry;
import com.fxkj.cloud.dbs.common.model.kv.service.TimeSeriesService;
import com.fxkj.cloud.drms.domain.ts.repository.TimeseriesRepository;
import com.google.common.base.Function;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.MoreExecutors;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

/**
 * <p>description: </p>
 * @author ww
 * @date 2025/3/18 9:58
 */
@Service
public class BaseTimeSeriesService implements TimeSeriesService {

    private final TimeseriesRepository timeseriesRepository;
    public static final Function<List<Integer>, Integer> SUM_ALL_INTEGERS = new Function<>() {
        @Override
        public @Nullable Integer apply(@Nullable List<Integer> input) {
            int result = 0;
            if (input != null) {
                for (Integer tmp : input) {
                    if (tmp != null) {
                        result += tmp;
                    }
                }
            }
            return result;
        }
    };

    public BaseTimeSeriesService(TimeseriesRepository timeseriesRepository) {
        this.timeseriesRepository = timeseriesRepository;
    }

    @Override
    public ListenableFuture<Integer> save(UUID rootOrganizationId, UUID productId, UUID deviceId, List<TsKvEntry> ts) {
        return doSave(rootOrganizationId, productId, deviceId, ts);
    }

    private ListenableFuture<Integer> doSave(UUID rootOrganizationId, UUID productId, UUID deviceId, List<TsKvEntry> ts) {
        List<ListenableFuture<Integer>> futures = new ArrayList<>();
        saveAndeRegisterFutures(rootOrganizationId, futures, productId, deviceId, ts);
        return Futures.transform(Futures.allAsList(futures), SUM_ALL_INTEGERS, MoreExecutors.directExecutor());
    }

    private void saveAndeRegisterFutures(UUID rootOrganizationId, List<ListenableFuture<Integer>> futures, UUID productId, UUID deviceId, List<TsKvEntry> ts) {
        doSaveAndRegisterFuture(rootOrganizationId, futures, productId, deviceId, ts);
    }

    private void doSaveAndRegisterFuture(UUID rootOrganizationId, List<ListenableFuture<Integer>> futures, UUID productId, UUID deviceId, List<TsKvEntry> ts) {
        futures.add(timeseriesRepository.save(rootOrganizationId, productId, deviceId, ts));
    }
}
